﻿//
//* created by hujin on 2020/10/6.
//

#ifndef C_MIPS_CMPLR_MATCHER_H
#define C_MIPS_CMPLR_MATCHER_H


#include "../token.h"
#include "../ast/ast.h"
#include "../ast/ast_statements.h"
#include <set>

class Matcher {
	TokenReader* reader;
	ProgramNode* root = nullptr;
	SymbolTable* symbolTable;
	bool error = false;
public:
    bool isError() const;

private:
    int curFuncType = 0;
    bool insideMain = false;

	Symbol readNext();

	void logError(const std::string& cause, const std::set<Symbol>& jumpTo);

	void logError(const std::string& cause, const std::set<Symbol>& jumpAfter, const std::set<Symbol>& jumpTo);

	template<typename T>
	T* addNode(T* node);

public:
	explicit Matcher(TokenReader* reader);


	ProgramNode* createProgramNode();

	CnstListNode* createCnstListNode();

	CnstDefNode* createCnstDefNode();

	IntNode* createIntNode();

	FunctionHeadNode* createFunctionHeadNode();

	CnstNode* createCnstNode();

	VarListNode* createVarListNode(bool checkFunction);

	std::vector<int> readArr(bool isInt);

	VarDefNode* createVarDefNode();

	FunctionVoidNode* createFunctionVoidNode();

	FunctionNode* createFunctionNode();

	BodyNode* createBodyNode();

	ParamsNode* createParamsNode();

	MainNode* createMainNode();

	ExprNode* createExprNode();

	TermNode* createTermNode();

	FactorNode* createFactorNode();

	StatNode* createStatNode();

	AssignNode* createAssignNode();

	IfNode* createIfNode();

	ConditionNode* createConditionNode();

	SwitchNode* createSwitchNode();

	SwitchTableNode* createSwitchTableNode(bool isInt);

	FuncCallNode* createFuncCallNode();

	VoidCallNode* createVoidCallNode();

	FuncCallParamsNode* createFuncCallParamsNode();

	StatListNode* createStatListNode();

	ScanfNode* createScanfNode();

	PrintfNode* createPrintfNode();

	ReturnNode* createReturnNode();

	IdentiferFactor* createIdentiferFactor();

	std::vector<std::vector<int>> readArr2(bool isInt);

	ForNode* createForNode();

	WhileNode* createWhileNode();

};


#endif //C_MIPS_CMPLR_MATCHER_H
